package com.wubai.ranger.api;


import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpEntity;
import org.apache.http.client.CookieStore;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import javax.xml.bind.DatatypeConverter;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;



public class AuditApi {
    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
    private final static Log LOG = LogFactory.getLog(AuditApi.class.getName());

    private static String printResponse(CloseableHttpResponse httpResponse) throws Exception {
        HttpEntity entity = httpResponse.getEntity();


        String entiryString = "";
        if (entity != null) {
            entiryString = EntityUtils.toString(entity);

        }

        EntityUtils.consume(entity);
        return entiryString;
    }

    public static void main(String[] args) throws Exception {
        String ipAddr = "10.203.13.253";

        String serviceName = "Ranger";

        String url;
        url = "https://" + ipAddr + ":28443/web/monitor/service/customize/1/" + serviceName + ".do";
        HttpGet httpGet = new HttpGet(url);

        //首次请求使用HTTP Basic认证，用户名和密码需要根据实际环境修改
        String authStr = "sharkdw" + ":" + "Huawei12#$@123";
        //根据协议要求，用户名密码需要使用base64编码
        String encoding = DatatypeConverter.printBase64Binary(authStr.getBytes("UTF-8"));
        //HTTP头中增加 HTTP Basic认证指示
        httpGet.setHeader("Authorization", "Basic " + encoding);

        //保存cookie。可以在一次HTTP Basic认证后，使用session维持会话，无需重复认证
        //20分钟内没有任何请求发送，则session会过期，需要重新登录
        CookieStore cookieStore = new BasicCookieStore();
        CloseableHttpClient httpClient = HttpClients.custom().setDefaultCookieStore(cookieStore).build();
        CloseableHttpResponse httpResponse = httpClient.execute(httpGet);


        url = "https://10.203.13.253:28443/web/api/v2/log/search";
        // 动态生成时间（示例：结束时间=当前时间，开始时间=24小时前）
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss");
        LocalDateTime endTime = LocalDateTime.now();
        LocalDateTime startTime = endTime.minusHours(2400); // 可调整时间差

        String startTimeStr = startTime.format(formatter);
        String endTimeStr = endTime.format(formatter);

        HttpPost httpPost = new HttpPost(url);

        httpPost.setHeader("Content-Type", "application/json;charset=UTF-8");
        String content = "{\"keyWord\":\": tbl\",\"sources\":[{\"sourceType\":\"CLUSTER\",\"clusterId\":1,\"clusterName\":\"\",\"services\":\"Hive:Hive:MetaStore\"}]" +
                ",\"logFileName\":\"metastore-audit\",\"minLogLevel\":\"INFO\",\"hosts\":\"\",\"startTime\":\"" + startTimeStr + "\"" +
                ",\"endTime\":\"" + endTimeStr + "\",\"timeOut\":\"120000\",\"maxLogsNum\":\"1000\"}";
        StringEntity stringEntity = new StringEntity(content);
        stringEntity.setContentEncoding("UTF-8");
        stringEntity.setContentType("application/json");
        httpPost.setEntity(stringEntity);


        httpResponse = httpClient.execute(httpPost);


        url = "https://" + ipAddr + ":28443/web/api/v2/log/search/progress/" + printResponse(httpResponse).split(":")[1]
                .replace("\"", "").replace("}", "");

        HttpGet httpGet2 = new HttpGet(url);

        CloseableHttpResponse httpResponse2 = null;
        int maxAttempts = 100; // max attempts
        int attempt = 0;
        while (attempt < maxAttempts) {
            try {
                httpResponse2 = httpClient.execute(httpGet2);
                if (printResponse(httpResponse2).contains("COMPLETE")) {
                    break;
                }
                Thread.sleep(10);
            } catch (Exception e) {
                System.err.println("ERROR: " + e.getMessage());
            }
            attempt++;
        }
        httpResponse2 = httpClient.execute(httpGet2);
        List<Map> details = jsonToMaps(printResponse(httpResponse2));
        ConcurrentHashMap<String, Integer> tableCounts = new ConcurrentHashMap<>();
        String regex = "tbl=hive.([\\w.]+)(?=\\s|\\|)";
        Pattern pattern = Pattern.compile(regex);
        StringBuffer stringBuffer = new StringBuffer();
        for (Map detail : details) {
            Matcher matcher = pattern.matcher(String.valueOf(detail.get("details")));
            if (matcher.find()) {
                StringBuffer tableName = new StringBuffer(matcher.group(1));
                if (!tableName.toString().equals(stringBuffer.toString())) {
                    tableCounts.compute(tableName.toString(), (k, v) -> (v == null) ? 1 : v + 1);
                }
                stringBuffer.setLength(0);
                stringBuffer.append(tableName.toString());
            }

        }
        sortAndPrint(tableCounts);
    }

    public static List<Map> jsonToMaps(String json) throws IOException {

        Map map = OBJECT_MAPPER.readValue(json, Map.class);
        return (List) (map.get("details"));
    }

    private static void sortAndPrint(Map<String, Integer> tableCounts) {
        // 将Map=>List
        java.util.List<Map.Entry<String, Integer>> list = new java.util.ArrayList<>(tableCounts.entrySet());

        // compareTo,DESC
        list.sort((o1, o2) -> o2.getValue().compareTo(o1.getValue()));

        for (Map.Entry<String, Integer> entry : list) {
            System.out.println(entry.getKey() + " " + entry.getValue() + "次");
        }

    }
}
